纯小白的Python教程 V5.0

关于

2017年2月到5月,参加了开智学堂「编程思维 Python 基础班」三期课程的课程学习教程。教是更好的学,所以整理出本教程4.0版本。

2023年,基于chatgpt4的支持,在这个教材版本上复习,并进一步完善小白学习python学习的教程,并且优化排版,更新到5.0版本。

个人系统:Mac os Sierra 10.12

前言 教6个月前的自己编程

有一首歌叫《写给十五岁的自己》,由日本的创作歌手angela aki创作。

歌的大概意思就是:你15岁时候,敏感,不开心,会把小的困难,看得很大。但是等长到现在的年纪,你就会发现,那些都是可以攻克的,回头看的话,其实也不是多困难的事情。但也正是那时候的你,单纯,不服输,坚持。所以,才会有现在的我。

教是更好的学,输出是更好的输入。输出的过程是发现自己无知的过程,如果没有自己输出的过程,无法证明自己会。所以记下自己的学习探索过程。内容会包括:

  • 对概念的理解
  • 预想的思路
  • 做过的尝试
  • 失败过的经历
  • 使用的方法

教谁呢?—— 教给6个月前的自己。就像《写给十五岁的自己》这首歌,跟过去的自己讲话,是有趣,有有意义的事情。这种时间视角的切换,会让学习场景,和困难,挫败,疲惫打斗的时候,增添一份勇气。

hi,6个月前,你什么都不懂,但是你想要学习python。而现在的我想告诉你,后来你啃下这块硬骨头了,而且做的也不错。

1 姿势提升

大牛说:

上手python的正确姿势是:立刻开始写代码!
学习编程最大的错误是:没有立即开始写代码。

没错,正确,很对。学编程需要大量的实践,就像是学习游泳,不下水肯定学不会,把游泳的方法技巧步骤流程都背下来也学不会。必须下水练习,在水里扑棱过,喝到水呛过,然后找到感觉。

学习编程像学习游泳,但不是真的是学习游泳,或者说不是一个有常识的成年人学习游泳。你听说过一个正常的成年人学游泳问这些问题吗?

  • 泳池在哪里?(在眼前啊)
  • 我怎么从水里出来?(泳池旁边就是栏杆可以爬上来啊)
  • 穿T恤牛仔可以下水吗?(当然不是,要换泳衣泳帽啊同学)
  • 我害怕被淹死。(不是深水区,踩到底脑袋就可以露出来呼吸了)

这些问题很傻是不是?纯小白学习编程,就是会有很多很多“蠢问题”。对于大牛来说,答案简直显而易见,对于小白来说,就是死磕一夜。

你摩拳擦掌准备好好学python,撩起袖子开始写代码。对啊对啊,学习写代码就和学游泳一样,就是要写起来。

然后还没迈出步子,你就被绊倒了。你站起来,又被绊倒了。为什么?姿势水平太低了。对于24k纯小白,不知道游泳池可以从侧边的栏杆攀爬下去,不知道要穿让阻力最小的贴身泳衣,不知道要戴上防水泳镜。

对于有编程基础的同学,立即开始写代码是正确的。对于没有编程的纯小白你,虽然没有错,但同时,你也必须知道,提升姿势水平更为迫切。

提供一条针对纯小白的最小可行的入门路线。对于纯小白,很大一部分是和姿势水平有关系的。一开始姿势水平低一点没有关系,但是再往后学的python时候,不要忘了提高自己的姿势水平。

这个路线图上的技能,学完了即可往前走。没解决的话,选择放弃,或者继续,或者暂时mark,先往前走,遇到问题,定位问题触发的点在哪里,找哪些途径解决,回头补上。

1.1 纯小白入门闯关

纯小白定义:没有学过任何一门编程语言。

第一关:基础能力

  1. 一定的英文水平,能看外文资料
  2. 科学上网,懂的,知道
  3. google,习惯一次输入3个以上的关键字
  4. 有靠谱环境(Linux/MAC比windows好)

第二关:编程思维

“学习 Py 的目标本身,从来不是 Python , 而是只有通过编程思维才能理解/接触到的真实世界的Cyber维度!”——大妈

1. 正念

  • 愿意尝试不同的编程体验
  • 不纠结类似 括号一定要单独一行,这种细节
  • 明确学习目标

2. 建立编程的概念

  • 一个神奇的故事——为什么程序能够工作
  • 如何向完全没有任何编程知识的人介绍编程

3. 建立程序思维

  • 为什么程序中的计数从 0 开始
  • 如何运行一个脚本
  • 如何输入/输出
  • 常见的数据类型
  • 常见的流程控制方式

4. 通过编程经验,掌握编程的基本元知识,建立起来基础的程序/代码/运行时等概念

可先学习JavaScript:这样,目测得追加4小时

  • 0.5 小时熟悉 Chrome 的调试工具
  • 1 小时通读 JS 教程, 理解 DOM 的操作概念和过程
  • 1 小时练习 JS 基础数据结构
  • 1 小时练习 JS 函式的使用
  • 0.5 小时,完成一个简单的页面交互

告诉自个儿,完成了一个软件的半成员

第三关:编程环境配置

  1. CLI:既然都要学编程了,那么用计算机的语言和计算机对话就是必须了。
  2. markdown:标记语法,不用花精力在排版上,专注于文字创作本身。
  3. git:代码很难管理,高级管理思想,释放代码管理中的精力,专注于写程序本身。
  4. Github:不仅可以通过git托管,还可以方便看代码,方便互相撩。
  5. gitbook:学不会编程,学会用git思想进行内容创作,管理文档,也是极好的。

1.2 python预热

完成 Python 环境的安装

确认在命令中输入 python 系统反馈正确的信息

1
2
3
4
Yina$ python3
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

yyuu/pyenv
支持你任性的使用指定版本的 Python 环境

pip
支持你任性的安装想安装的第三方模块

IPython
支持你任性的用各种姿势探索 Python

python第一印象:Python脚本直解!

这42行代码,是可执行的
同时包含了几乎 80% 的 Python 代码常见情景

用4天时间来建立程序思维

day0 为什么程序中的计数从 0 开始? 先尝试回答这一问题
day1 明确如何运行一个 Python 脚本,以及如何输入/输出
day2 体验 Python 中常见的数据类型
day3 探索 Python 中常见的流程控制方式

进入 IPython 交互式编程环境中

参考官方文档中的教程
或Learn Python The Hard Way 前 21 课中有关部分
多使用 dir(),help() 来检验运行时内存里的 Python 对象是否如自己的设想
用10分钟,专心熟悉以下核心数据类型:

  • 数字
  • 文本, UTF-8/中文 文本
  • 列表,嵌套列表,列表推导式 简单的 for in 循环
  • 字典,嵌套字典
  • 用 Sublime Text 编写几个简短的脚本

在终端上运行, 检验想法是否正确

完成以下常见工程行为:

  • 函式, 完成一个函式,可以拼接两行文本为新文件保存到硬盘
  • 模块, 将函式发布为一个模块,可以在另外一个脚本中调用
  • 文件, 调用此模块,将两个指定 .txt 文件的内容,逐行交错合并为一个新文件
  • 网络, 改进此模块,可以将两个指定网页的内容, 逐行交错合并为一个新文件

或是Learn Python The Hard Way 参考 22 课之后的有关部分练习
在 32分钟以内, 完成以上建议的行为。然后,成为Pythonista 了, 自在的使用 Python 来完成梦想。这就不是小白教程范畴了。

1.3 初学编程正念

为什么要学习编程

刚学习python种种折腾,包括 CLI、github、gitbook、git、learn python the hard way。四周后终于可以假装自己像一个hacker一样写代码了,准备下水游泳了。但老是被呛,怀疑自己要学习python这个选择。它到底是啥,为什么要选择要趟这个水?

人生苦短,我学python

这个是很美好的一句口号。人生苦短,时间应该花费在美好的,值得经历的事情上面。可是没有学过python,没有学过任何一门编程语言之前,我并没有能力判断它好不好,为什么好。

他们说:“python是最容易的编程语言之一”

再简单也是计算机语言,既然是计算机语言,它就和自然语言不一样,需要克服我们自然语言的思维方式和使用方式。更何况,学习一门新的自然语言也并非易事。说它简单,那个是和其他计算机语言相比较的结果。

所以,学习python既不会轻松,也不会容易和美好。对于真小白,真的是虐心之旅。

知道分子的求知欲

计算机语言是真正意义上的通用世界语,规则稳定。因此,作为一名知道分子,想选择一门容易入门的编程语言感受一下。如果有能力做自己想做的事情,当然是最好不过的。

这个理由说的过去,但是假大空,遇到困难就会满足于“好像懂了”,但是不会死磕把东西做出来。反正也不是想转行做程序员啊。做不出来也不会对不起老板发的工资。

获得hacker思维

“学习 Py 的目标本身,从来不是 Python , 而是只有通过编程思维才能理解/接触到的真实世界的Cyber维度!” ——大妈

另一个令我记忆深刻的例子是很小的时候学习编程语言。受影响最深的是一种思考方式──在跑程序之前,要反复浏览代码,在脑子里进行预演;而不是写完程序直接跑,出错了再说。这是节省时间提高效率的重要方式。——笑来

可以自己解决一个问题

编程经验->作什么?好象没有直接关系,其实,这就是为什么要学习编程的根因之一。
世界已经基本上被电脑管理了。除了编程,普通人很难能通过数据模式来理解/改进世界。

练习英语和写作

学习了十几年的英语。但是学习英语的课程还是遍地开花。营销点往往是更标准的发音,口语这些。然而语言还是工具而已。打开世界的工具。
开智课程强调要去看外文的材料。大妈的攻略第一条就是英文要好。

同理,写作也是。开智强调要输出,写教材。

学习写作,学习英语,有一个真实的场景,比教材中模拟的场景,更有意义。

对小白最友好的python教程之一

这个目标,是在学习进入一般之后产生的。我对重新再造一个轮子没有兴趣。然而以我的编程能力,并不能做出太牛逼的东西。我确实觉得编程能力是很重要的一种能力,重要体现在这种思维方式。我也希望更多人可以摆脱懒惰,固化,想当然的思维习性,更适应未来的信息化的,到处都是大数据的,智能化的时代和社会。

个人网站

学习进入第五周的任务是做web端的网站开发。跟着书一步步做,打了一周的出租车,每天熬夜到十二点后。还是不会做!得到这样结果,很有挫败感。

放空了两天,洗完澡就睡,谢谢抒发情绪的日记,回头整理教程,看自己漏掉什么?

还有几周就要接触。既希望这么辛苦的时间早点过去。也希望自己真的学有所成。

最后几周,就要组队交大作业。

回到一开始这个问题。有一个答案是:我想建立一个个人博客。之前听极客电台,有一期节目是,要嫁就嫁一个有个人网站的人。原因是:

  • 个人博客通过时间累积,持续不断产生价值,累计产生价值。
  • 相对于第三方托管,内容审核的风险比较小。

虽然有一个个人网站很酷的样子,但是顾虑也是很多:

  • 按照我不喜欢随便瞎写的要求,很可能也会半途而废掉。
  • 现在通过第三方托管,也很方便。
  • 如果只是个人网站,要推广,获得阅读量,现在并不是很容易了。

1.4 编程元思维

程序的每个部件都有自己独特的功能,我们只要负责将这些部件以合适的逻辑连接起来,就可以完成新的功能。——《一个神奇的故事:为什么程序能够工作》

编程为什么难?

编程语言的交流对象是计算机。编程语言的理解并不难,和自然语言学习相比,困难点在于,计算机语言的容错性极低。不能出错误,否则就无法成功交流。

假如你在学习一门自然语言,可能学的不是很好,比如:I speak a little english.虽然用词,语句组织都只有60分,但是可以让绝大多数会英语的人懂你。

“写程序和写诗一样需要练习 我的程序无法将电脑写炸了 电脑很笨需要告诉丫怎么作”——大妈

冷冻疗法

该疗法提出的背景:

ch6部署heroku遇到一系列问题,在群里求助:

@yina

卡在buildpacks这里了。虽然已经设置buildpacks,并且确认已经设置到app,但是git push后,返回的错误信息书Failed to detect set buildpack。这是什么原因呀?我已经发了issue,各位教练同学有空求指点一二。

@珠海-MAC-Zoom.ོQuiet

Buildpacks | Heroku Dev Center https://devcenter.heroku.com/articles/buildpacks

django - Heroku/python failed to detect set buildpack - Stack Overflow http://stackoverflow.com/questions/39282911/heroku-python-failed-to-detect-set-buildpack

Heroku 使用教程 - 简书 http://www.jianshu.com/p/7bc34e56fa39

FLASK在HEROKU上部署成功,请多多指教 - 初学入门 - CoCode http://cocode.cc/t/flask-heroku/3729/10

@yina

其实大妈提供的这几个链接,基本都看过,各种方案,也都试过,但是还是没有成功

@珠海-MAC-Zoom.ོQuiet

这时,俺的经验就是:杀光,重新部署,从0开始, 一步步进行,先完成一个干净的无/最小 app 的空间部署,再逐步追加,直到发现崩溃的那一个配置行。

即,冷冻疗法

因为能自主设计发现/证明/纠正/改进/预防… 错误的一系列思维,就是编程本身哪….而根本不是各种课程宣称的语法/OOP/框架/etc.

其实相同的经验大家都有:中学作物理/化学 实验失败了怎么作?学霸们一眼看出哪儿有问题,解决就好…俺只能还原所有东西, 重新按照实验手册一步步重新来,然后发现次序/计量/方向….各种基础错误

在成功的基础上步进, 才知道哪儿出错的,否则,再怎么嗯哼, 也只是拼运气了

MVP:最小可执行流程

MVP:最小可走通的流程。
步骤:建立空代码,每走通一个功能,就记录一个版本。
MVP好处:及时给予正面反馈,提升自我效能感,学习体验比较好

背景:上述冷冻疗法

MVP概念演示
我放弃了部署ch4的应用,跟着一个YouTube的教程,完成了MVP的flask框架的python应用在heroku的部署。同时,卡包也分享了大妈在上期课程中,用ch1的任务演示MVP的流程。

  1. 建立空代码

一个正确的开始就是,可运行的没有任何问题的空代码

  • pythonMVP空代码
1
2
3
4
5
#!/user/bin/env python
#coding:utf-8

if __name__ == '__main__':
pass
  • flask框架的MVP空代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import flask
Flask = flask()

@route(/,)
return index
```


## 1.5 编程环境

### CLI:对话界面

**什么是CLI?**

还记得windows出来之前的dos操作系统吗?大概就是这个意思,直接用命令和计算机互动。

和后来的桌面系统相比,这种直接以命令方式进行的互动方式,容错率低,门槛高,很难推广称为商业化的产品。

然而小白要假装成极客的话,还是要会用的。至少运行python是一定需要通过这个界面的。

**CLI常用命令**

#### `cd` 打开当前文件
对于纯小白来说,这是必须要学会命令。因为运行程序必须先打开文件路径,在该文件下运行。
有些文件路径比较长,输入不方便。可以通过编辑,将XX拷贝为路径名称。如果编辑没有找到,可以在帮助里搜索,很容易跳出来。

#### 文件路径如何添加

1 拆成2步操作

jiangyinadeMacBook-Pro:~ Yina$ cd desktop
jiangyinadeMacBook-Pro:desktop Yina$ cd Py103
jiangyinadeMacBook-Pro:Py103 Yina$

1
2

2直接输入文件路径:上级文件名/文件名

jiangyinadeMacBook-Pro:~ Yina$ cd desktop/Py103
jiangyinadeMacBook-Pro:Py103 Yina$

1
2
3
4
5
6
7

3 帮助——路径——复制路径,再粘贴
![屏幕快照 2017-02-28 下午9.46.29](media/14871693658727/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202017-02-28%20%E4%B8%8B%E5%8D%889.46.29.png)



#### `ls` 列出当前文件夹中的文件

jiangyinadeMacBook-Pro:Py103 Yina$ ls
Chap0 Chap5 ISSUE_TEMPLATE.md
Chap1 Chap6 README.md
Chap2 Chap7 SUMMARY.md
Chap3 Chap8 note
Chap4 Chap9

1
2

#### `pwd` 显示当前文件的路径

jiangyinadeMacBook-Pro:Py103 Yina$ pwd
/Users/Yina/desktop/Py103

1
2

#### `mkdir` 新建文件

jiangyinadeMacBook-Pro:Py103 Yina$ mkdir test.txt
jiangyinadeMacBook-Pro:Py103 Yina$ ls
Chap0 Chap5 ISSUE_TEMPLATE.md
Chap1 Chap6 README.md
Chap2 Chap7 SUMMARY.md
Chap3 Chap8 note
Chap4 Chap9 test.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93


### Github:真实情景

#### 学python为什么要用github
因为这是一个编程和写代码工作行业的bbs,程序猿和程序媛的社交网站啊。

没有错,但这并不是github的精髓。

我是一个零基础小白,我有一个python任务要完成,但是没有人可以指导我。任务比较忙,但是我的时间又比较紧,我放弃和“一定要独立完成,证明自己可以”的自尊心抵抗。

然而,连看同学作业的过程都没有那么顺利。复制黏贴代码之后,发现运行不成功,于是我去微信群求助,然后发现,这次任务有好几个python文件,我没有全部复制黏贴下来,代码不完整,就无法运行。

如果我要观摩好几个同学的作业,就得一个一个复制黏贴好麻烦,学习体验太差了有没有?

于是我就想到了GitHub的folk和clone的功能,此时此刻显得非常有必要,然后就折腾出来了。

通过这个过程中内心的纠结,切身体会到这个功能的需求场景了~

#### 如何通过github提高姿势水平

**预期目标:**

* 一键folk, 轻松把别人的好代码弄到自己这里来
* 一键clone到本地,在本地写代码,保持专注,有心流状态的创作
* 一键commit提交代码, 实现本地和线上仓库的同步

**步骤:**
1、注册github
2、去别人页面,看到中意的仓库,点击页面的folk按钮。
folk的功能,是一键把别人的仓库,弄到自己这里的功能。
价值是可以大大提高模仿jie ji的效借鉴参考牛人的效率。
3、在自己的页面中,就可以看到这个folk过来的仓库了。
4、下载github桌面端
github桌面端不在 appstore,要去官网下载。(小白可能会踩的坑,对的我就踩到过)
5、在github的仓库下,点击clone按钮,然后在github桌面端,就会把这个仓库下载本地了,需要建立一个文件夹
6、然后你可以在本地这个文件夹随便玩耍了,写代码,运行代码,如果要做处改动,就提交commit,然后在你自己页面的仓库里,这个仓库也就发生了变化

**练习**
你可以做这样一个尝试:如何通过2个动作把廖雪峰的python课程在本地运行学习


#### 看别人代码的正义性

@ 深圳-Mac-scrat-scratlzj

> 我一直卡在ch4,又很抵触看别人的代码。

@珠海-MAC-Zoom.ོQuiet

> '''...又很抵触看别人的代码''
为什么?
教练来, 也是出示别人的代码的哪?
就和写作一样, 不破万书无以成自家风骨,
别人的代码不看, 那这世界上, 没有什么软件是写的出来的...
毕竟, IT 发展了快一个世纪了,
已经没有什么是能直接凭空写出来的代码了,
都在前人无数基础上嗯哼出来的,
也正是因为这一生态,才令编程界的发展比其它各界要高速的多的多的多!

@安徽阜阳-OS X-武黎-fatfox2016

> 我就是一路抄出来。
在这里要感谢@广州-Ubuntu-大猫-simpleowen @上海 - Win10 - Yifan - Yifan127。
我是全文抄一遍的,在用print大法拆完凿碎。


### Git:代码管理

我不是来学python的吗?为什么要学git?一开始我也不知道为什么。

上网查了一些概念,知道git是一种版本管理的方法。什么?写程序还要专门学一个版本管理方法?

github是基于这一版本管理方法,搭建的平台。哦,原来github不仅仅是码农界的bbs,程序猿和程序媛的社交网站。

后来,在一次做任务中,深深体会到代码管理过程中的痛,软件代码管理的重要性,git解决的问题的价值,背后的思想。想到开学典礼上大妈说的那句:

> git 是一种世界观

git是分布式的代码管理系统。简而言之,之前的代码管理很麻烦,用git进行代码版本管理,炒鸡炒鸡厉害。

**git作为一种抽象的时空观**

工作区
仓库,或者叫做版本库
暂缓区
远程仓库

**体验git**

#### 在CLI操作git命令,本地进行仓库管理

注册

~ Yina$ git config –global user.name”yina”
~ Yina$ git config –global user.email”niceyina@gmail.com

1
2

在电脑本地建立git目录和仓库

~ Yina$ mkdir git-tutorialgit inti

1
2

#### `git init` 初始化仓库

~ Yina$ cd git-tutorial git-tutorial
Yina$ git init
Initialized empty Git repository in /Users/Yina/git-tutorial/.git/ #目录存储当前目录内容所需的仓库数据
:git-tutorial Yina$

1
2
#### git status 查看仓库状态
显示git仓库的状态,常用。

Yina$ git status
On branch master# 我们正处在master分支下面
Initial commit
nothing to commit (create/copy files and use “git add” to track)# 没有可以提交的内容

1
2

建立README.md文件,重新查看状态。

jiangyinadeMacBook-Pro:git-tutorial Yina$ touch README.md
jiangyinadeMacBook-Pro:git-tutorial Yina$ git status
On branch master
Your branch is up-to-date with ‘origin/master’.
Untracked files:
(use “git add …” to include in what will be committed)

README.md

nothing added to commit but untracked files present (use “git add” to track)
jiangyinadeMacBook-Pro:git-tutorial Yina$

1
2

#### `git add` 向暂存区添加文件

$ git add README.md
$ git status
On branch master
Your branch is up-to-date with ‘origin/master’.
Changes to be committed:
(use “git reset HEAD …” to unstage)

new file:   README.md
1
2
3


#### `git clone`下载命令

jiangyinadeMacBook-Pro:desktop Yina$ git clone https://github.com/miguelgrinberg/flasky.git
Cloning into ‘flasky’…
remote: Counting objects: 830, done.
remote: Total 830 (delta 0), reused 0 (delta 0), pack-reused 830
Receiving objects: 100% (830/830), 140.72 KiB | 126.00 KiB/s, done.
Resolving deltas: 100% (462/462), done.

1
2
3
4
5
6
7
8
9

git clone

```~ Yina$ git clone https://github.com/yiiina/learn-python3.git
Cloning into 'learn-python3'...
remote: Counting objects: 286, done.
remote: Total 286 (delta 0), reused 0 (delta 0), pack-reused 286
Receiving objects: 100% (286/286), 82.97 KiB | 6.00 KiB/s, done.
Resolving deltas: 100% (83/83), done.

git remote add 添加远程仓库

github创建仓库路径: git@github.com yiiina/git-tutorial.git

git remote add把github上面的仓库设置成本地仓库的远程仓库。

1
git remote add orgin git@github.com yiiina/git-tutorial.git

git push 推送至远程仓库

git checkout签出

git checkout其实是用版本库里的版本替换工作区的版本,无论工作区是修改还是删除,都可以“一键还原”。

1
2
3
4
5
6
7
8
9
10
11
12
13
jiangyinadeMacBook-Pro:flasky Yina$ git checkout 4a
Note: checking out '4a'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

git checkout -b <new-branch-name>

HEAD is now at 4bd4ac9... Chapter 4: Web forms with Flask-WTF (4a)

比较区别git diff

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
jiangyinadeMacBook-Pro:flasky Yina$ git diff 2a 2b
diff --git a/hello.py b/hello.py
index 062cbc2..2bf2aed 100644
--- a/hello.py
+++ b/hello.py
@@ -7,5 +7,10 @@ def index():
return '<h1>Hello World!</h1>'


+@app.route('/user/<name>')
+def user(name):
+ return '<h1>Hello, %s!</h1>' % name
+
+
if __name__ == '__main__':
app.run(debug=True)

2 启程python

2.1 ready go

你会想象,学习一门软件的样子,是在那边敲代码。事实上,首先你会被其他一些东西难住。比如说:

安装python

我当时听说,ios系统是自带python的。但是我没有找到。

  • 解决方案:官网重新下载安装。
  • 后续思考:为什么当时python没有找到呢 ?
  • 最终结论:反正都装好了,不纠结。

运行一个Python 脚本

交互界面下,不是真的运行一个程序。正常步骤如下:

  • 用编辑器写一个程序
  • 保存成.py的脚本文件:比如abc.py
  • 在CLI中,在文本所在的文件夹,打开该脚本文件名:python abc.py

python交互界面

在CLI中输入python,可以显示当前python版本,并且进入python 交互界面的。

1
2
3
4
5
jiangyinadeMacBook-Pro:desktop Yina$ python
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 12:39:47)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>

一开始不知道有这个交互界面,效率很低,后来知道原来这么容易就可以获得这样一个交互界面,输出代码,是可以很快看到结果的,反馈非常即时。

在学习基础的数据类型的时候,基本上都可以在交互界面中获得及时反馈。学习效率提高很多。

help()和dir()获取帮助信息

help() 交互模式下,用help向python请求帮助
help() 具体的模块帮助信息
dir() 内置dir()函数检查模块(以及其对象)的内容
quit() 回到交互状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
>>> import math
>>> dir(math)
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
>>> help(math)

Help on module math:

NAME
math

MODULE REFERENCE
https://docs.python.org/3.6/library/math

The following documentation is automatically generated from the Python
source files. It may be incomplete, incorrect or include features that
are considered implementation detail and may vary between Python
implementations. When in doubt, consult the module reference at the
location listed above.

DESCRIPTION
This module is always available. It provides access to the
mathematical functions defined by the C standard.

FUNCTIONS
acos(...)
acos(x)

Return the arc cosine (measured in radians) of x.
:

2.2 交互式编程环境配置:最快反馈

关于编程环境的问题:对小白来说可以理解为IDE环境、终端环境、程序文件+终端执行,其实最后都是终端调用shell执行。—— @大妈

命令行界面

在命令行界面输入python,出现交互式界面

IDLE

下载python自带的交互界面。
和命令行界面相比,更加人性化,不同的内容会标出不同的颜色。

terminal or IDLE

IDLE和terminal都没有运行

sublime编辑器

推荐开发环境推荐使用sublime编辑器(理由:颜色识别,自动函数等)。

Ipython

Ipython= notebook+jupyter;notebook优点是,网页上同时展示,环境,思路,代码同时展示;限制是,比较难装且与标准程序开发环境有所区别

大妈对此作了解答:分

两个方向,“Ipython= notebook[网页上同时展示,环境,思路,代码同时展示;but 难装;]+jupyter。”

ipython notebook

一个基于web的ipython shell!

notebook使用起来和ipython差不多,不过修改起来方便得多,并且可以建多个notebook,所以使用起来各种方便

2.3 42行代码Python脚本解析,包含80%常见情景 ⭐️

__ coding: utf-8 __ # 中文用户用这行声明编译,同时文件本身也得储存成UTF-8编码
quick python script explanation for programers
给程序员的超快速脚本解说 #单行注释

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
_*_ coding: utf-8 _*_
import os # 模块名,导入os.py

def main(): #
print 'hello world'

print"tihs is alice's greeting."
print'this is bob\'s greeting.'

foo(5,10)

print '='*10
print 'current working directory is'+ os.getcwd()

counter = 0
counter += 1

food = ['apple','oranges','cats']

for i in food:
print 'i like to eat' + i

print 'count to ten:'
for i in range(10):
print i

def foo(param1,secondparam):
res = param1 + secondparam

print '%s plus %s is equal %s' % (param1,secondparam,res)
if res < 50:
print 'foo'
elif (res >= 50) and (param1 == 42) or (secondparam == 24):
print 'bar'
else:
print 'moo'
return res
'''a multi-
line string,but can also be a multi-line comment.'''

if __name__ == '__main__':
main()

运行成功是这样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
hello world
tihs is alice's greeting.
this is bob's greeting.
5 plus 10 is equal 15
foo
==========
current working directory is/Users/Yina/Desktop
i like to eatapple
i like to eatoranges
i like to eatcats
count to ten:
0
1
2
3
4
5
6
7
8
9

if name == ‘main‘:

当你打开一个.py文件时,经常会在代码的最下面看到
if __name__ == '__main__':

模块是对象,并且所有的模块都有一个内置属性 name。一个模块的 name 的值取决于您如何应用模块。

如果 import 一个模块,那么模块name 的值通常为模块文件名,不带路径或者文件扩展名。但是您也可以像一个标准的程序样直接运行模块,在这 种情况下, name 的值将是一个特别缺省”main“。

在cmd 中直接运行.py文件,则name的值是’main‘;

而在import 一个.py文件后,name的值就不是’main‘了;

从而用if __name__ == '__main__'来判断是否是在直接运行该.py文件
如:

1
2
3
4
5
6
7
#Test.py
class Test:
def __init(self):pass
def f(self):print 'Hello, World!'
if __name__ == '__main__':
Test().f()
#End

你在cmd中输入:

1
2
C:>python Test.py
Hello, World!

说明:”name == ‘main‘“是成立的

你再在cmd中输入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
C:>python
>>>import Test
>>>Test.__name__ #Test模块的__name__
'Test'
>>>__name__ #当前程序的__name__
'__main__'
```

无论怎样,Test.py中的"__name__ == '__main__'"都不会成立的!
所以,下一行代码永远不会运行到!



## 2.4 Python2和Python3

### python2和python3关系

软件会不断迭代更新。一般来说选择最新的那种就好了,如果老版本使用习惯了,可以继续用。但是问题不大,一般就是功能上的差异,不同版本都是可以打开的。

但是python2和python3,这两个版本不兼容。也就是说,用其中一种语言写的代码,用另一个版本的软件是打不开的。

感受一下,有点像这种情况:同样在吴语区,上海话和苏州话也是不一样,彼此不完全听懂的。

有些教程直接从3开始教。《learn python the hard way》这本书是教2的,并且并没有告诉2和3的区别。

### python2和python3如何切换?

问题描述:

- 怎么知道,当前运行代码的是python2还是python3呢?
- 如何在电脑中切换这两种语言呢?
- 遇到的困难不知道是p2还是p3在运行,怎么用python3运行?

中间被一个方案绕进去很久,折腾了一两个小时也没有成功。

最后解决方案很简单:命令行`python`,改成`python3`

之后安装各种扩展,也记得要安装在不同的版本下。安装在python2下面,python3是不能用的哦。反过来也是一样。

### python2和python3语法上的区别
两者之间差别有好多。但是这时候python2好多语法也没有弄懂。那么,就通过3个练习,找到3个区别吧。

用《learn python the hard way》中第1个到第3个练习改写来说明。

1. print 变成了函数,print后面的文本要加上()

用exercise1示例说明。

python2

print “hello world”
print “hello again”
print “i like typing this.”
print “this is fun.”
print ‘yay! printing.’
print “i’d rather you ‘not’.”
print ‘I”said” do not touch this.’

1
python3

print (“hello world!”)
print (“hello again”)
print (“i like typing this.”)
print (“this is fun.”)
print (‘yay! printing.’)
print (“i’d rather you ‘not’.”)
print (‘I”said” do not touch this.’)

1
2
3
4
5
6

2. 因为支持了Unicode (utf-8),所以可以识别中文

用exercise2示例说明。

python2

print “I can have code like this.”
print “this will run”

1
2

python3

print (“我可以像这样编码”)
print (“this will run”)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

3. 输入:raw_input变成input



## 2.5 面向对象编程

### 面向对象编程语言和自然语言

选择python学习编程,很重要的原因之一是,它比较简单。简单的原因之一是,它更接近人类自然语言。接近自然语言的原因之一是,它是面向对象编程的。接近自然语言是因为,class的思想原本就是源于人类语言的分类原理。

对于小白来说,想太多这些思想性的东西本身益处不大。但编程语言的抽象程度太高,没有容错的空间,这会让小白很崩溃。从自然语言获得启发,可能会比较容易理解对象的用户。可以把对象当成名词,方法是动词。主谓结构是自然语言中,最常见的语法。

同学去拿杯水。 你是主语,拿杯水是谓语。
小明去拿杯水。小明说主语,拿杯水说谓语。

这里同学是类,小明说实例,拿杯水是方法,可以定义的。在python里,主语和谓语可以通过一个`.`连接。一个名字有相应的属性,一个动词也有特定的描述。比如说,同学有性别,成绩,身高等属性;动词有能力,要求等定义。在python中,名词的属性和动词的要求也可以自定义,用各种变量来描述。

### 关于对象的范畴
没有特定的定义,所有数据类型都是对象
类是自定义的对象

### 教科书式描述面向对象编程
面向对象编程是一种程序设计思想。
该思想抽象出class,根据class创建instance,面向对象的抽象程度比函数高,因为一个class即包含数据,又包含操作数据的方法。
把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
面向对象程序设计把计算机是做一组对象的集合,每个对象可以接收其他对象传递过来的消息,并处理这些消息。计算机执行的就是一系列消息在各个对象之间的传递。
三大特点:数据封装,继承和多态

### 面向过程编程和面向对象编程比较

面向过程

std1 = {‘name’:’michael’,’score’:98}
std2 = {‘name’:’bob’,’score’:81}

def print_score(std):
print ‘%s,%s’%(std[‘name’],std[‘score’])

1
2

面向对象

class Student(object):

def __init__(self,name,score):
    self.name = name
    self.score = score

def print_score(self):
    print '%s%s' % (self.name,self.score)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

## 2.6 Python基础概览 ⭐️


### 输入/输出
输入 raw_input( )
输出 print

### 语句(控制流程)
赋值语句:a = 3
模块导入 :import math
条件语句:if/elif/else
循环语句 for,while
无条件分支语句

### 对象
数据
数字 number
整数 int
浮点数 float
字符串 sting
布尔值 boolean
列表 list
字典 dict
byte
none
tuple
set
类 class
文件

### 方法
符号:# % / > """ """
变量
函数
运算符
算数运算符 + - * / % ** //
比较运算符 = = 等于 !=不等于 > < >= <=
逻辑运算符
布尔类型:True,False
布尔运算:and,or,not


概览图
![](media/14861298830099/14861298990971.jpg)


他们看上去是怎样的?(交互环境)

输出:print、 数据类型:数字(整数)、字符串

print 1
1
print”yina”
yina
print”yina is learn python”
yina is learn python

1
输入  raw_input()

#第一种写法
print “how old are you?”,
age = raw_input()

#第二种写法
age = raw_input(“how old are you?”)

print “so,you are %r old” % (age)

1
2

符号:# 注释 % 格式化字符串(占位符),理解为一种偷懒的方式,让主句简短,相应的内容凡在后面

name = “yina” # 这是注释,不会被显示
lesson =”python”
print”%s is learn %s”%(name,lesson)
yina is learn python

1
2

符号:转义符\,换行\n """ 换行开始和换行结束,可以同时多行换行

days = “mon tue wed thu sat sun”
months = “jan\nfeb\nmar\napr\nmay\njun\njul\naug”

print “here are the days: “, days
print “here are the months: “, months

print “””
there’s something going on here
with the three double-quotes.
we’ll be able to type as much as we like.
even 4 lines if we want, or 5, or 6.
“””

1
2

变量,赋值语句,数据:布尔值 boolean,运算(算数运算,比较运算,逻辑运算)

a=1
b=2
print a
1
print b
2
print a+b
3
a==b
False
a!=b
True
a==b and a!=b
False
a==b or a!=b
True
not a==b
True

1
2

定义函数的格式

def 函数名(参数 1,参数 2,…,参数 n):
函数体(语句块)

1
2

模块导入

import math
from math import pow

1
2
3

条件语句 if/elif/else
必须要通过缩进方式来表示语句块的开始和结束

if 条件 1:
执行的内容 1
elif 条件 2:
执行的内容 2
else:
执行的内容 3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89

循环语句 for

循环语句 while

输入 raw_input( )

对象
列表 list
字典 dict
byte
none
tuple
set

类 class
文件

方法
符号:# % / > """ """ ""
变量
函数
运算符
语句(控制流程)
赋值语句:a = 3
模块导入 :import math
条件语句:if/elif/else
循环语句 for,while
无条件分支语句

### python 扩展软件包
还记得之前说编程语言,其实是一种胶水语言。所谓的胶水胶的对象,就是一个个的模块嘛。

自己写的那部分,有一些,如果别人轮子已经做好,也无需重新造轮子,拿过来粘在自己车上就是。

那么这些轮子,就是一些可扩展的软件包了。

* pip

软件包管理系统,用python写成,用来安装和管理软件包。
简而言之,pip可以很方便得把要用的轮子装上去,或者卸下来。

安装软件
`pip install packagename`

移除软件包
`pip uninstall packagename`

* pip freeze

pip freeze命令可以查看到应用中所有轮子,以及轮子的版本

`$ pip freeze
click==6.7
Flask==0.12
gunicorn==19.6.0
itsdangerous==0.24
Jinja2==2.9.5
MarkupSafe==0.23
requests==2.13.0
virtualenv==15.1.0
Werkzeug==0.11.15
`

* requirement.txt

在部署程序到服务器的时候,需要有一个档案告诉服务器程序中所有用到过的轮子,以及轮子的版本。这个文档是requirements.txt,
通过“需求”档案来管理软件包及其相应版本的列表功能。

requirements.txt也可以通过pip来建立。

`pip install -r requirements.txt`
or
`pip freeze > requirements.txt`

## 2.8 入门练习 Learn Python the Hard Way ⭐️

这本书算是比较公认的入门教程。它强调动手,在练习中学习。它的理念差不多就是先下水,再学游泳动作的游泳教学法。不过他把动作切分得很小,新手在他的指引下不会被一口呛死。而且,还可以通过小小的努力获得的反馈中,获得正向的学习动力。

练习不多,总共是52个。把这些代码以及一些基础知识点过一遍。你可以把它当成这本教材的教辅。

最一开始的任务,就是先从《learn python the hard way》的练习入手。通过简单的代码运行成功,获得正面的反馈。然后从输入的代码和运行的结果中,感知python语言的规则。

### 1、 print
无处不在的print
显示print后面的内容
python3中,print是函数,后面要加()
注意( )的格式,格式不对会报错
"" 和''的结果是一样的

print “hello world!”

1
2
3
4
 
2、
对代码的注释
运行的时候不会显示出来

a comment, this is so you can read your program later.

any thing after # is ignored by python.

print “I can have code like this.”# and the comment after is ignored

1
2

3、数字、运算、布尔值运算

print “now i will count the eggs:”

print 3+2+1-5+4%2-1/4+6

print “it is true that 3+2<5-7?”

print 3+2<5-7

print “what is 3+2?”,3+2
print “what is 5-7?”,5-7

print “oh,that is why it’s false.”

1
2
3
4

4、变量和赋值
变量是对一组数据的名称,
变量可以对该组数据赋数值,也可以赋予文本

cars = 100
car_driven = drivers
变量也可以进行运算
cars = 100
space_in_a_car = 4.0
drivers = 30
passengers = 90
cars_not_driven = cars - drivers
cars_driven = drivers
carpool_capacity = cars_driven * space_in_a_car
average_passengers_per_car = passengers/cars_driven

print “there are”, cars,”cars available.”
print “there are only”, drivers, “drivers available.”
print “there will be”,cars_not_driven,”empty cars today.”
print “we can transport”, carpool_capacity,”people today.”
print “we have”,passengers,”to carpool today.”
print “we need to put about”, average_passengers_per_car,”in each car”

1
2
3
4
5
6
7

5-8 % 格式化字符串
:理解为一种偷懒的方式,让主句简短,相应的内容凡在后面
字符串可以套入变量
%s 跟字符串
%d 跟数据
%r repr 综合的返回

my_name = ‘zed a. shaw’
my_age = 35 #not a lie
my_height = 74 # inches
my_weight = 180 # lbs
my_eyes = ‘blue’
my_teeth = ‘white’
my_hair = ‘brown’

print “let’s talk about %s” % my_name
print “he’s %d inches tall.” % my_height
print “he’s %d pounds heavy.” % my_weight
print “actually that’s not too heavy.”
print “he’s got %s eyes and %s hair.” % (my_eyes, my_hair)
print “his teeth are usually %s depending on the coffee.” % my_teeth

#this line is tricky,try to get is exactly right
print “if i add %d, %d, and %d i get %d.” % (my_age, my_height, my_weight, my_age + my_height + my_weight)

1
2

6、

x = “there are %d types of people.” % 10
binary = “binary”
do_not = “don’t”
y = “those who know %s and those who %s.” % (binary, do_not)

print x
print y

print “i said %r.” % x
print “i also said ‘%s’.” % y

hilarious = False
joke_evaluation = “isn’t that joke so funny?! %r”

print joke_evaluation % hilarious

w = “this is the left side of …”
e = “a string with a right side.”

print w + e

1
2
3


7、

print “mary had a little lamb.”
print “its fleece was white as %s.” % ‘snow’
print “and everywhere that mary went.”
print “.”* 10# what’d that do?

end1 = “C”
end2 = “h”
end3 = “e”
end4 = “e”
end5 = “s”
end6 = “e”
end7 = “B”
end8 = “u”
end9 = “r”
end10 = “g”
end11 = “e”
end12 = “r”

watch that comma at the end.try removing it to see what happens

print end1 + end2 + end3 + end4 + end5 +end6,
print end7 + end8 + end9 + end10 + end11 + end12

1
2
3
4
5
6
7
8

有逗号:
Cheese Burger
逗号去掉:
Cheese
Burger

8、

formatter = “%r %r %r %r”

print formatter % (1,2,3,4)
print formatter % (“one”,”two”,”three”,”four”)
print formatter % (True, False, False, True)
print formatter % (formatter,formatter,formatter,formatter)
print formatter % (
“i had this thing.”,
“that you could type right.”,
“but it didn’t sing.”,
“so I said goodnight.”
)

1
2
3
4
5
6
7

9-10 转义符,换行
\n 换行
""" 换行开始和换行结束,可以同时多行换行
* 列表
\ 转义符
\t 缩进

here’s some new stranger stuff, remember type it exactly.

days = “mon tue wed thu sat sun”
months = “jan\nfeb\nmar\napr\nmay\njun\njul\naug”

print “here are the days: “, days
print “here are the months: “, months

print “””
there’s something going on here
with the three double-quotes.
we’ll be able to type as much as we like.
even 4 lines if we want, or 5, or 6.
“””

1
2
3
4
5
6
7
8
9
10
11
12

11-12 输入和输出
age=raw_input()
age是一个变量
raw_input() 对应的具体的数值外部输入
raw_input的两种句式
1
print “how old are you?”
age = raw_input()
2
age = raw_input("how old are you?")
print "how old are you?",

age = raw_input()
print “how tall are you?”
height = raw_input()
print “how much do you weight?”,
weight = raw_input()

print “so,you are %r old, %r tall and %r heavy.” % (age, height, weight)

1
2

12、

age = raw_input(“how old are you?”)
height = raw_input(“how tall are you?”)
weight = raw_input(“how much do you weight?”)

print “so,you’re %r old, %r tall and %r heavy.” % (age,height,weight)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

13 导入模块,import语句
? sys 模组(modules, librairies)
把sys模组中的参数变量导入进来
sys python的标准库
sys 和module,dicteries 这些概念类似,模组,模块…
argv 参数变量 你传递给python的参数
argv 参数变量,倒入的文件作为变量 #?
解包:将所有参数放到一个变量下面,每个参数赋予一个变量名,含义,把argv中的东西解包,并将所有参数依次赋予左边的变量名
import语句:
调用python的标准库功能
导入文件,可以避免脚本过于冗长
from sys import argv

script,first,second,third = argv

print "the script is called:",script
print "your first variable is:",first
print "your second variable is:",second
print "your third variable is:",third

14 prompt > 提示符
使用传递符号,> 提醒用户这里有输入信息

from sys import argv

script, user_name = argv
prompt = ‘> ‘

print “hi %s, I’m the %s script.” % (user_name, script)
print “i’d like to ask you a few questions.”
print “do you like me %s?” % user_name
likes = raw_input(prompt)

print “where do you live %s?” % user_name
lives = raw_input (prompt)

print “what kind of computer do you have?”
computer = raw_input(prompt)

print “””
alright, so you said %r about liking me.
you live in %r. not sure where that is.
and you have a %r computer. nice.
“”” % (likes,lives,computer)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

15-17 文档
15 打开文档,显示文档内容
使用argv参数变量,获取文件名称这个参数
定义一个变量名称,来和这个文档联结。
打开读取文件 txt=open()
呈现当前文件 txt.read()

script, filename = argv 倒过来写会如何?
报错信息:
Traceback (most recent call last):
File "ex15.py", line 4, in <module>
argv = script, filename
NameError: name 'script' is not defined
倒过来放,就是要重新定义变量了,但是argv是默认的参数变量。
这里是传递参数的过程。

txt和 txt_again指向的是同一个txt文件,这个文件有了2个变量名称。
txt_again是用户输入的变量名称,有可能会和txt指代的是不一样。如果这个文档内容没有导入,会出现什么?
lpthw Yina$ python ex15.py ex15_sample.txt
...
type the filename again:
> ex15sample.txt
Traceback (most recent call last):
File "ex15.py", line 14, in <module>
txt_again = open(file_again)
IOError: [Errno 2] No such file or directory: 'ex15sample.txt'
jiangyinadeMacBook-Pro:lpthw Yina$
如果把txt_again这个变量也改成txt会如何?
试了一下,结果不会变化。

from sys import argv


script, filename = argv

txt = open(filename)

print "here's your file %r:" % filename
print txt.read()

print "type the filename again:"
file_again = raw_input("> ")

txt_again = open(file_again)

print txt_again.read()
sample.txt
this is stuff i typed into a file.
it is really cool stuff.
lots and lots of fun to have in here.

e16 删除文件内容和写入文件内容
truncate() 清空文件,小心使用
write(stuff)将stuff写入文件
close() 关闭文件,和保存一个意思
from sys import argv

script,filename = argv

print "we're going to erase %r." % filename
print "if you don't want that,hit CTRL-C(^C)."
print "if you do want that,hit RETURN."

raw_input("?")

print "opening the file..."
target = open(filename,'w')

print "truncating the file. goodbye!"
target.truncate()

print "now i'm going to ask you for three lines."

line1 = raw_input("line 1: ")
line2 = raw_input("line 2: ")
line3 = raw_input("line 3: ")

print "i'm going to write these to the file."

target.write(line1)
target.write("\n")
target.write(line2)
target.write("\n")
target.write(line3)
target.write("\n")

print "and finally,we close it."
target.close()
e17 复制文件
len
exist 命令 将文件名字符串作为参数,如果文件存在,返回true,否则返回false
cat 命令
?
e3 100-25*3%4
97
3+2+1-5+4%2-1/4+6
7
e7,cheese burger, print 换行实现的是空格,而不是换行,为什么?
%r和%s的区别

from sys import argv
from os.path import exists

script,from_file,to_file = argv

print”coping from %s to %s” % (from_file, to_file)

we could do these two on one line too, how?
in_file = open(from_file)
indata = in_file.read()

print “the input file is %d bytes long” % len(indata)

print “does the output file exist? %r” % exists(to_file)
print “ready,hit RETURN to contune, CTRL-C to abort.”
raw_input()

out_file = open(to_file,’w’)
out_file.write(indata)

print “alright,all done.”

out_file.close()
in_file.close()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73


嵌套关系:变量套字符和数字,字符串可以套变量,函数可以套变量

18-21 函数
e 18 函数
微型脚本,小命令,使用def新建函数
def 变量名称(参数)
函数体

e 19
函数和变量的关系
函数的变量和脚本的变量没有连接
参数可以是数字,变量,也可以是运算
函数很灵活
加分作业表示:编一个函数,然后用10种方法运行~


e 20 函数和文件如何写作

e 21 return 函数值

e 22 -26 复习

e 25
导入到编译器使用
函数可以一步一步做的简单,也可以通过嵌套一步到位
""" """ 文档注释

e27-28 布尔运算,逻辑关系
e29-31 条件控制语句
x += 1 就是x = x + 1
条件控制语句: if 语句
if语句包含if语句的嵌套
if语句背后是布尔运算的逻辑关系


e32 流程控制语句:for循环语句和列表
e33 while 循环

e34 处理列表
e38 还是和列表相关的

e35 函数分支
e36 修复bug
e37 复习

e39 字典
e40-e44 类 对象

模块:嵌套变量和函数
另一个文件导入之后,可以使用模块中的函数和变量
使用模块和使用字典有类似地方,不过语法不一样

python中的通用模式
建立key=value的容器
通过key调取value

字典:[key]-value
模块:.key-函数,返回值

类和模块比较相似,有一组函数和数据,通过 . 来调用

例子:mystuff 分别为字典,模块,和类

提取东西的3种方式:dict, module,class


e41
导入网页中的数据:
WOERDS 建立空列表,通过append()把数据写入列表
append()的参数是word.strip()
通过for语句一行一行读取网页中的数据,通过strip()去掉每一行数据中的空格。

import random

from urllib import urlopen
import sys
WORD_URL = “http://learncodethehardway.org/words.txt"
WORDS = []
for word in urlopen(WORD_URL).readlines():
… WORDS.append(word.strip())
WORDS
[‘account’, ‘achiever’, ……, ‘dust’]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

这里PHRASES是一个字典数据,有6组key-value值。每一个value是对这个key进行注释的字符串。翻译一下每一个key-value。

1、class %%%(%%%)::创建一个名字叫%%%,并且属于%%%的类

2、"class %%%(object):\n\tdef __init__(self, ***)":为%%%这个类初始化定义,并且包含self和***的参数。

3、class %%%(object):\n\tdef ***(self, @@@)":%%%这个类有一个一个叫***的函数,函数的参数包括self 和@@@

4、*** = %%%():创建%%%的实例,***

5、让实例***使用***这个函数,并且传递参数self和@@@

6、***.*** = '***':从***获得***的属性并且设置为***


# 3 用python解决问题

编程能力是一种解决问题的能力。如果问题没有很好地被解决,知道再多也没用。

## 3.1 天气查询工具

### 任务描述:公网可查的天气查询程序
功能:完成一个最简天气查询程序,运行在命令行界面,实现以下功能:

* 输入城市名,获取该城市的天气情况;
* 输入指令,获取帮助信息(一般使用 h 或 help);
* 输入指令,获取历史查询信息(一般使用 history);
* 输入指令,退出程序(一般使用 quit 或 exit)。


### 任务拆解:解决问题的思路
####有交互,需要用户输入信息
python2和python3中有一个区别:

python2:raw_input

userinput= raw_input(“查询天气请输出城市名” )

python3: input

userinput= input(“查询天气请输出城市名” )

1
2
3
4
5
6
7
8
#### 流程控制程序
4种不同条件下的结果:使用条件判断语句:if…elif…else

* “if”“elif” 条件判断语句,如相应的判断条件成立时,执行后面的语句
* “else” 条件判断语句,如任何判断条件都不成立时,则执行后面的语句

解决只能输入一次的问题,while可以实现无限循环
“while true” 条件判断语句,如果判断条件永远为true,程序将会无限循环执行

while True:
if :
elif:
elif:
elif:
else:

1
2

#### quit #简单

if userinput=”quit”
quit()

1
2

#### help #简单

#实现方法1 直接print 帮助信息
if userinput=”help”
print “””
输入城市名,可获取该城市的天气情况;
输入help,获取帮助信息;
输入history,获取历史查询信息;
输入quit,退出程序
“””

#实现方法2 调用help文档

1
2
3
4
5
6
7
8
9
10
11
  


#### 输入城市名,获取该城市的天气情况 # 困难
难点:如何应用天气数据

####历史查询 # 困难

### 难点击破
####如何应用天气:打开文档,读取文档内容,内容赋值到变量,关闭文档
打开文档

f=open(“weather_info.txt”,”r”)
with open(‘’weather_info.txt”,”r”) as f:

1
2

读取文档内容

f.read()
f.readlines() #读取了整个文件,读取速度会很慢

1
关闭文档

f.close()

1
2

用一个变量接受内容,内容赋值到该变量

weather=f.read()
weather=f.readlines()

1
2
3
4
5
6
7
8

###如何把文档中的数据转化成dict呢
建立字典数据
`dict={}`

城市和天气分开,并形成key和value的一一对应
`Python split()`通过指定分隔符对字符串进行切片,拆成了一个数组,一个list给key,一个list给value
几种不同形式的参考:

for line in f:
key,value=line.strip().split(‘,’)
dict[key]=(value)

for items in weather:
item = item.split(“,”)
city_dict[[item[0]]=item[1]

city_dict = dict(item.split(“,”) fot item in weather)

for line in f.readlines():
line = line.strip(‘\n)
line = line.split(‘,’)
key= line.pop(0)
value=line.pop(-1)
dict[key]=value

1
2

#### 查询天气

elif userinput in dict:
print(“%s城市的天气为%s”%(userinput,dict[userinput]))

1
2
3
4
5
6

如何查询历史呢?
历史是什么类型的数据?——有序、“键”
历史是一个list
历史有顺序,有列表的痕迹,可用一个二元元祖数据表示
history的是想到append()到一个数组里,调用起来会方便一点

history = []

elif userinput in dict:
print (“%s城市的天气为%s”%(userinput,dict[userinput]))
history.append(userinput)

elif userinput == “history”:
for i in history:
print (“i”)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

#### 代码
写代码中遇到很多错误反馈。一次次调整,也是一次次学习~
作为小白,犯了很多初级错误,但是反复修改,感觉对语法规范掌握更好一些了。
比如:
错误:quit
正确:quit()

错误:elif:userinput == "help":
正确:elif userinput == "help":

错误:f=open("weather_info")
正确:f=open("weather_info.txt")

附上代码:

#coding:utf-8”

f=open(“weather_info.txt”)

dict = {}

for line in f:
key,value=line.strip().split(‘,’)
dict[key]=value

history = []

while True:
userinput=input(“请输入要查询天气的城市名:”)

if userinput == "quit":
          quit()        

elif userinput == "help": 
        print (""" 
        输入城市名,可获取该城市的天气情况;
          输入help,获取帮助信息;
          输入history,获取历史查询信息;
          输入quit,退出程序
        """ )        

elif userinput in dict:
         print ("%s城市的天气为%s"%(userinput,dict[userinput]))
         history.append(userinput)

elif userinput == "history":
        for i in history:
                print ("i")

else:
         print (""" 
        输入城市名,可获取该城市的天气情况;
          输入help,获取帮助信息;
          输入history,获取历史查询信息;
          输入quit,退出程序
        """ )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17


## 3.2 可查即时数据的天气查询工具

###任务描述:公网可查的天气查询程序
基本功能同任务1:完成一个天气查询程序,运行在命令行界面,实现以下功能:

* 输入城市名,获取该城市的天气情况;
* 输入指令,获取帮助信息(一般使用 h 或 help);
* 输入指令,获取历史查询信息(一般使用 history);
* 输入指令,退出程序(一般使用 quit 或 exit)。

新增功能:查询时获取的是最新的天气情况,且包含更多维的天气数据

### 任务拆解:解决问题的思路

#### 任务1代码分析

coding:utf-8” #中文字符编码
变化1:任务1中,是打开本地天气数据文本,任务3,要调用实时数据,要调用API
f=open(“weather_info.txt”)
任务1 实现城市名称和天气之间的一一对应,建立一个字典数据
任务3 搜索结果是多维的,字典里面,会嵌套列表数据,这一步暂时不确定要不要改动
dict = {}

因为数据源的变化,所以这部分都要改掉
for line in f:
key,value=line.strip().split(‘,’) #为key和value赋值
dict[key]=value #key和value之间建立对应关系

任务1中历史是一个列表数据
任务3中,历史是一个列表嵌套数据了
history = []

以下代码执行阶段,只要变量名称设定不变,那么也就不会变,可以复用
while True:
userinput=input(“请输入要查询天气的城市名:”)

if userinput == "quit":
      quit()    

elif userinput == "help": 
    print (""" 
    输入城市名,可获取该城市的天气情况;
      输入help,获取帮助信息;
      输入history,获取历史查询信息;
      输入quit,退出程序
    """ )    

elif userinput in dict:
     print ("%s城市的天气为%s"%(userinput,dict[userinput]))
     history.append(userinput)

elif userinput == "history":
    for i in history:
        print ("i")

else:
     print (""" 
    输入城市名,可获取该城市的天气情况;
      输入help,获取帮助信息;
      输入history,获取历史查询信息;
      输入quit,退出程序
    """ )
1
2

#### 新任务拆解

coding:utf-8”

调用API的实时数据
显示多维的数据,字典数据的一个key,对应一个列表数据,这一步暂时不确定要不要改动

dict = {}

处理调用过来的数据,定义key和value的对应,其中value是列表数据

任务3中,历史是一个列表嵌套数据了
history = []

elif userinput in dict:
     print ("%s城市的天气为%s"%(userinput,dict[userinput]))
     history.append(userinput)

elif userinput == "history":
    for i in history:
        print ("i")
1
2
3
4
5
6
7
8

#### 如何实现实时数据查询:API调用
通过API调用在线数据,实现数据实时查询

#### 安装requests模块,通过request模块和API交互,发送请求
通过pip安装request

python3.6自带pip,但是要更新一下`install -U pip`

install -U pip
jiangyinadeMacBook-Pro:desktop Yina$ pip install -U pip
Requirement already up-to-date: pip in /Library/Frameworks/Python.framework/Versios/2.7/lib/python2.7/site-packages

1
2
3
4
5
6

问题:默认文件都是python2.7,更新的也是python2.7的pip

如果安装requests默认两个版本都可以用,就没有问题了。

安装requests `pip install requests`

jiangyinadeMacBook-Pro:desktop Yina$ pip install requests
Collecting requests
Retrying (Retry(total=4, connect=None, read=None, redirect=None)) after connection broken by ‘NewConnectionError(‘<pip._vendor.requests.packages.urllib3.connection.VerifiedHTTPSConnection object at 0x103146e90>: Failed to establish a new connection: [Errno 65] No route to host’,)’: /simple/requests/
Downloading requests-2.13.0-py2.py3-none-any.whl (584kB)
100% |████████████████████████████████| 593kB 1.4MB/s
Installing collected packages: requests
Successfully installed requests-2.13.0

1
2
3

测试renquests是否安装成功:
python2是安装成功的,但是python3下没有

jiangyinadeMacBook-Pro:desktop Yina$ python
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 12:39:47)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.

import requests

jiangyinadeMacBook-Pro:desktop Yina$ python3
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.

import requests
Traceback (most recent call last):
File ““, line 1, in
ModuleNotFoundError: No module named ‘requests’

1
2
3
4
5
现在只有python2版本下成功安装好requests,2种解决方案:
1. 配置可以切换python2和python3的yyuu/pyenv,切换到python3,然后再重新安装requests
2. 用python2做这次任务

在 @leilayanhui教程中发现可疑通过pip3 install requests安装到python3版本,试了一下,成功了

jiangyinadeMacBook-Pro:desktop Yina$ pip3 install requests
Collecting requests
Using cached requests-2.13.0-py2.py3-none-any.whl
Installing collected packages: requests
Successfully installed requests-2.13.0
jiangyinadeMacBook-Pro:desktop Yina$ python3
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type “help”, “copyright”, “credits” or “license” for more information.

import requests

1
2
3
4
5
6
7

#### 选择心知天气的 API
卡包中提供了几种,心知,彩云,还有一个是国外的
先选择国内的数据
试用了一下彩云,发现它需要审核之后才能用。免费的使用有问题,返回的json数据表示配额已用完


import requests
r=requests.get(‘https://api.caiyunapp.com/v2/TAkhjf8d1nlSlspN/121.6544,25.1552/realtime.json')
r.json()
{u’status’: u’failed’, u’error’: u’API quota is exhausted’}

1
2

换成心知的,返回的数据是这样的:

import requests

url=’https://api.thinkpage.cn/v3/weather/now.json?key=wzgjycshjgiuisxr&location=beijing&language=zh-Hans&unit=c'
r=requests.get(url)
r.json()
{u’results’: [{u’now’: {u’text’: u’\u6674’, u’code’: u’0’, u’temperature’: u’3’}, u’location’: {u’name’: u’\u5317\u4eac’, u’country’: u’CN’, u’timezone_offset’: u’+08:00’, u’path’: u’\u5317\u4eac,\u5317\u4eac,\u4e2d\u56fd’, u’timezone’: u’Asia/Shanghai’, u’id’: u’WX4FBXXFKE4F’}, u’last_update’: u’2017-02-02T17:50:00+08:00’}]}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

#### 什么是JSON,JSON的数据结构,JSON的数据和python数据的转化
* JSON(JavaScript Object Notation),**javascript对象表示法**
* javascript世界上最流行的脚本语言,属于web语言,被设计向html页面增加交互性
* 一种轻量级的**文本数据交换格式。**
* 理想的**数据交换语言**
* 易于人阅读和编写,易于机器解析和生成
* 独立于语言和平台,JSON解析器和JSON库支持许多不同的编程语言

**JSON建构于两种结构:**

1. “名称/值”对的集合(A collection of name/value pairs)
2. 值的有序列表(An ordered list of values)

因为大部分计算机语言是以各自形式支持这种数据结构的,所以它可以在这些语言之间进行交换。

**JSON具有以下这些形式:**

对象 object:{}
一个无序的“‘名称/值’对”集合。string:value
{string1:value1, string2,value ……stringn:valuen}

数组 array :[]
值(value)的有序集合。
[value1,value2,...valuen]

值 value
字符串(string)、数值(number)、true、false、 null、对象(object)或者数组(array)
这些结构可以**嵌套**

**JSON的数据类型和python数据类型的转化**
JSON Python
object dict
array list
string str
number(int) int
number(real) float
true True
false False
null None



#### 返回的数据结构分析
心知天气提供了一个返回结果示例。和代码里r.json()返回的数据结构是一样的。分析这个JSON数据结构,如果它转化为python数据,会是什么样的?

先简化这个数据结构:

{
“results”: [{
“location”: {
“name”: “西雅图”,
“country”: “US”,
},
“now”: {
“text”: “多云”,
“temperature”: “14”,
},
“last_update”: “2015-09-25T22:45:00-07:00”
}]
}

1
2


{
“results”: [ ]
}

1
2
3

从里往外看,最里面一层 {},有名称-值的对的集合,所以是json中的
对象,转化成python是dict

{“name”:”西雅图”,”country”:”US”}
{“text”:”多云”,”temperature”:”14”}

1
2
3

第二层也是json对象,内部有3个名称,“location”,“now”和“last_updata”。
其中"location"和"now"的value都是一个dict

{“location”:{},”now”:{},”last_update”:2015-09-25T 22:45:00-07:00}

1
2

第二层的对象,再套入一个数组[],数组中只有1个value,就是这个对象。对应到python,它是一个列表

[{ “location”: {},”now”: {}, “last_update”: “2015-09-25T22:45:00-07:00” }]

1
2

再外面一层:这个列表作为 value,和名称为result配对。建立最外层的对象,这个对象中,只有一个名称-值的对

{ “results”: []}

1
2
3
4
5
6
7

#### `load()`把JSON的数据,转成python的数据
从api获取数据之后,需要把JSON的专成python结构的
[读写JSON数据](http://python3-cookbook.readthedocs.io/zh_CN/latest/c06/p02_read-write_json_data.html)

这篇文章里,发现可以通过`json.dump()`和`json.loads()`实现互相转化。这里我要用到的就是`json.loads()`
一开始并不成功,报错信息是:

data=json.loads(r)
TypeError: expected string or buffer

1
2

后来把参数改成r.txt就成功了

r=requests.get(url)

data = json.loads(r.text)
data
{‘results’: [{‘location’: {‘id’: ‘WX4FBXXFKE4F’, ‘name’: ‘北京’, ‘country’: ‘CN’, ‘path’: ‘北京,北京,中国’, ‘timezone’: ‘Asia/Shanghai’, ‘timezone_offset’: ‘+08:00’}, ‘now’: {‘text’: ‘多云’, ‘code’: ‘4’, ‘temperature’: ‘3’}, ‘last_update’: ‘2017-02-05T22:45:00+08:00’}]}

1
2
3
4
5
6
7

一个猜测:json是文本数据


#### 使用request发送请求:post or get?

先看看get和post分别会返回什么东西呢

import requests
url=’https://api.thinkpage.cn/v3/weather/now.json?key=wzgjycshjgiuisxr&location=beijing&language=zh-Hans&unit=c'
r=requests.get(url)
r

r=requests.post(url)
r

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

心知天气上,给到的返回结果是200
404在这里不知道是什么意思,但是常识,好像是找不到页面的意思~

看到一篇关于[post和get的文章](http://mp.weixin.qq.com/s?__biz=MzI3NzIzMzg3Mw==&mid=100000054&idx=1&sn=71f6c214f3833d9ca20b9f7dcd9d33e4#rd)写得挺有意思:


#### 需要输出的是什么类型的数据
{'results': [{'location': {'id': 'WX4FBXXFKE4F', 'name': '北京', 'country': 'CN', 'path': '北京,北京,中国', 'timezone': 'Asia/Shanghai', 'timezone_offset': '+08:00'}, 'now': {'text': '多云', 'code': '4', 'temperature': '3'}, 'last_update': '2017-02-05T22:45:00+08:00'}]}


输入:name:北京

输出:"北京当前的天气是%s,温度是%s"%('text','code')

3个key-value:"name":"北京","text":"多云","temperature":"14"

第一个key-value,和后面两个key-value,构成一个key-value

{北京:{"text":"多云","temperature":"14"}}



#### 如何获取数据呢? —— 通过函数,返回需要的数据
通过requests.get, 返回了一个数据结构。但是因为没有具体的数值。这时候要向API传递参数,然后返回值。

复习函数
函数包括:函数名称,函数体,参数,返回值

通过def语句自定义函数,
def 函数名称(参数):
函数体
return 返回值

函数的参数:必选参数,默认参数,可变参数,关键字参数



数据

####心知天气 API 调用示例

import json
import sys
import requests
from utils.const_value import API, KEY, UNIT, LANGUAGE
from utils.helper import getLocation

def fetchWeather(location):
result = requests.get(API, params={
‘key’: KEY,
‘location’: location,
‘language’: LANGUAGE,
‘unit’: UNIT
}, timeout=1)
return result.text

if name == ‘main‘:
location = getLocation()
result = fetchWeather(location)
print(result)

1
2

调整

import json
import sys
import requests
utils=’https://api.thinkpage.cn/v3/weather/now.json?key=wzgjycshjgiuisxr&location=beijing&language=zh-Hans&unit=c'
from utils.const_value import API, KEY, UNIT, LANGUAGE
from utils.helper import getLocation

def fetchWeather(location):
result = requests.get(API, params={
‘key’: KEY,
‘location’: location,
‘language’: LANGUAGE,
‘unit’: UNIT
}, timeout=1)
return result.text

if name == ‘main‘:
location = getLocation()
result = fetchWeather(location)
print(result)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61




## 3.3 内网版天气查询系统

任务:完成一个网页版天气查询程序,实现以下功能:
基本功能

* 输入城市名,获取该城市最新天气情况
* 点击「帮助」,获取帮助信息
* 点击「历史」,获取历史查询信息
部署在命令行界面

### 任务分析(更新)
WSGI 接口函数
请求
响应
首页格式
submit 表单输入
天气应用程序(可复用)
HTML网页文本

### web建站基础知识
### CS & BS

| CS client and server | BS browser server |
| --- | --- | --- |
| 软件在桌面端,数据库在服务器 | 浏览器发起需求,数据库在服务端 |
| 升级时候需要客户端一一升级 | 更加灵活 |


### BS关键词
浏览器 服务器 HTTP HTML REQUEST RESPONCE

附:关于建站技术,知乎上这个[帖子](https://www.zhihu.com/question/22689579/answer/22318058),对小白比较友好。
![](media/14865634767885/14877736096833.jpg)


### HTML & HTTP
HTML:文本,定义网页,可通过CSS JS增加有表现性和交互性
HTTP:协议,如何上传HTML,浏览器和服务器如何通信

网站交互实际上就是在HTTP协议下,请求和响应的循环过程。

### WSGI
web应用程序,入口都是一个**WSGI处理函数,针对每个HTTP请求进行响应**。

免去底层代码的工作:包括TCP连接,HTML原始请求和响应格式

### web框架
**多个URL路径和多种请求类型**
在一个应用中,问题不仅仅在于处理HTTP请求,问题是处理很多个不同的url,每一个都有独立的请求,比如get和post.依次从变量中取出信息,一个个判断,代码很难维护。

**web框架,用来处理url到函数的映射**


### flask框架
flask是小型的,可扩展的的一个web框架。

安装:

Yina$ pip3 install flask

1
2
3
4
5

### flask扩展
通过一系列flask扩展的安装,可以体会到扩展的作用,体会作为一种“胶水语言”的编程语言。以下是几种flask扩展。

**Flask-Script 支持命令行选项**

Yina$ pip3 install flask-script

1
**Flask-Moment 本地化日期和时间**

Yina$ pip3 install flask-moment

1
2

**Flask-Bootstrap 响应模版**

Yina$ pip3 install flask-bootstrap

1
2
3

**flask-WTF 扩展处理web 表单**
对独立的WTForms包进行了包装,把处理web表单变成愉悦的体验

Yina$ pip3 install flask-wtf

1
2
3
4
5

#### 扩展的初始化
专为flask开发的扩展都在flask.ext命名空间下。
从命名空间导入扩展,把程序实例作为参数,传递给构造函数,初始化主类的实例。
创建的对象可以在各个扩展中使用。

from flask.ext.script import Manger
from flask.ext.script import Bootstrap
from flask.ext.script import Moment

manger = Manger(app)
bootstap = Bootstrap(app)
moment = Moment(app)

#……

if name == ‘main‘:
manage.run()

1
2
3
4
5
6
7

### flask的WSGI接口函数
flask实际上就是一个WSGI的接口函数。
该接口函数包括构造函数和视图函数。

#### 构造函数:Flask类的对象是程序
程序实例是`Flask`类的对象。该对象处理来自客户端的所有请求。

from flask import Flask
app=Flask(name)

1
2
3
4
5
6
7
8
9
10
11

Flask 类
app是Flask的一个实例,这个实例参数就是程序名称。
参数是程序主模块或者包的名字,flask用这个参数决定程序根目录。

#### 路由,装饰器,视图函数

路由:程序,处理url和函数之间的关系
flask通过python的装饰器在内部自动把url和函数关连起来
`app.route`修饰器
视图函数`index()`:返回值是响应

@app.route(‘/‘)
def index():
return ‘

hello,world!


1
2
3


#### `run()`启动服务器

if name=’main‘:
app.run(debug=true)

1
2
3
4
5
6

`if __name__='__main__':`
直接执行该脚本才启动web服务器,如果由其他脚本引入,则不会执行。


#### 添加一个动态路由

from flask import Flask
app = Flask(name)

@app.route(‘/‘)
def index():
return ‘

Hello World!

@app.route(‘/user/‘)
def user(name):
return ‘

Hello, %s!

‘ % name

if name == ‘main‘:
app.run(debug=True)

1
2
3
4
5
6
7
8
9
10
11


### 请求-响应循环
BS的核心就是,浏览器发出请求,服务器作出回应。
如此循环往复。

#### 请求上下文
请求对象:封装客户端发送的HTTP请求。
视图函数如何访问请求对象?
将其作为参数传入视图函数。
避免大量参数把视图函数弄乱,flask使用**上下文临时把某些对象变为全局可访问**。

from flask import request

@app.route(‘/‘)
def index():
user_agent = request.headers.get(‘user_agent’)
return’

your browser is %s

% user_agent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
flask使用上下文让特定变量在一个线程中全局可访问,同时不干扰其他线程。从而使得request当作全局变量使用。

程序上下文变量

* current_app
* g


请求上下文变量

* request
* session

调用上下文变量之前要激活。


#### 请求调度:找到处理该请求的视图函数
URL映射:url和视图函数的对应关系
flask生成映射:`app.route` or `app.add_url_rule()`

检查映射

from f import app

app.url_map
Map([ index>,
' (HEAD, GET, OPTIONS) -> static>])

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

路由:
`/` app.route定义的路由
`/static/<filename>` flask添加的特殊路由,访问静态文件
请求方法:
HEAD, GET, OPTIONS
由路由处理,每个路由指定了请求方法

#### 请求钩子:通用函数
执行代码和处理请求的顺序

注册通用函数
避免每个视图函数使用重复代码
注册函数可在请求被分发到视图函数之前或者之后调用

钩子通过修饰器实现。
before_first_request:
before_request:
after_request:
teardown_request:

#### 响应
返回值:响应内容
参数
字符串:html页面
状态码:200,表明请求已被处理
字典
response对象
重定向
abort函数

#### 使用模版生成响应

业务逻辑和表现逻辑混在一起会导致代码难以理解和维度
把表现逻辑迁移到模版中可以提升程序的可维护性

模板:包含响应文本的**文件**,文件夹:templates,文件名:index.html ..


渲染
`render_template`:用真实值替代变量,在返回得到最终响应字符串
jinja2:渲染用的引擎
`render_template`参数
文件名,键对值


控制结构
在模版中使用条件控制语句,for循环,宏(函数),重复使用可保存在单独文件中
模版继承,类似于python代码中的类继承


### 通过web表单和用户交互(模版的一个功能)
跨站请求伪造保护
表单类
把表单渲染成HTML
在视图函数中处理表单
重定向和用户会话
flash消息


#### 表单类
使用Flask-WTF时,每个web表单由一个继承自`Form`的类表示
定义表单中一组字段
每个字段用对象表示
字段对象可附属一个或者多个验证函数
验证函数:验证用户信息提交是否符合要求

from flask.ext.wtf import Form
from wtforms import StringField,SubmitField
from wtforms.validators import Required

class NameForm(Form):
name = StringField(‘what is your name’,validators = [required()])
submit = SubmitField(‘Submit’)

1
2
3
4
5
6
7
8
9
10

#### 表单渲染成HTML





### 其他
#### python版本管理 pyenv
小白进阶路线图中有提到过python环境配置,其中有一条是通过pyenv来管理python版本。测试一下,之前有装过,但是没有用过。

jiangyinadeMacBook-Pro:desktop Yina$ pyenv
pyenv 1.0.6
Usage: pyenv []

1
2
3

#### 创建虚拟环境
《flash web开发》中建议在虚拟环境中开发,但是我还是不是很会使用虚拟环境。

jiangyinadeMacBook-Pro:~ Yina$ git clone http://github.com/miguelgrinberg/flasky.git
Cloning into ‘flasky’…
remote: Counting objects: 830, done.
remote: Total 830 (delta 0), reused 0 (delta 0), pack-reused 830
Receiving objects: 100% (830/830), 140.72 KiB | 220.00 KiB/s, done.
Resolving deltas: 100% (462/462), done.
jiangyinadeMacBook-Pro:~ Yina$ cd flasky
jiangyinadeMacBook-Pro:flasky Yina$ git checkout 1a
Note: checking out ‘1a’.

You are in ‘detached HEAD’ state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

git checkout -b

HEAD is now at e4777c9… Chapter 1: initial version (1a)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28



## 3.4 公网版天气查询系统

### 目标:把应用搬到云端
将自己的应用由内网搬到公网
可以在任意设备访问你的应用
尝试自动化部署应用
本章任务:完成一个公网版天气查询程序
部署在云端,比如部署在 Heroku 上
实现以下基本功能:
输入城市名,获取该城市最新天气情况
点击「帮助」,获取帮助信息
点击「历史」,获取历史查询信息
进阶任务:将天气数据封装成 API,供别人调用

PaaS:platform as a service
SAE
阿里云
Daocloud

Heroku
Heroku :是一个支持多种编程语言的云平台,使用 Heroku 建立应用

### 最小flask应用在heroku的部署记录

查看当前文件,有一个app.py

jiangyinadeMacBook-Pro:flask-deploy Yina$ ls
app.py

1
2

#### pip freeze

jiangyinadeMacBook-Pro:flask-deploy Yina$ pip freeze
click==6.7
Flask==0.12
gunicorn==19.6.0
itsdangerous==0.24
Jinja2==2.9.5
MarkupSafe==0.23
requests==2.13.0

1
2
3
4
5

#### requirements.txt文件
记录了当前程序的所有依赖包及其精确版本号。

作用是用来在另一台PC上重新构建项目所需要的运行环境依赖。

jiangyinadeMacBook-Pro:flask-deploy Yina$ pip freeze > requirements.txt

1
检查一下,在文件夹中,多了requirements.txt 这个文档。

jiangyinadeMacBook-Pro:flask-deploy Yina$ ls
app.py requirements.txt

1
2
3
4
5
6
7
8
9
10
11
12
13

#### Procfile文件
把一个Procfile文件放入文件夹。
文件名没有任何后缀。
文件要放在代码的根目录。
文件写入需要运行的命令。格式:
name:command

文件内容:
web: gunicorn app:app

web:这个进程类型将会连接到Heroku的HTTP路由栈,在部署时接收web流量
gunicorn: 用于运行web的执行指令

jiangyinadeMacBook-Pro:flask-deploy Yina$ ls
Procfile app.py
requirements.txt

1
2

#### 运行python,进行确认

jiangyinadeMacBook-Pro:flask-deploy Yina$ python app.py

  • Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
    127.0.0.1 - - [26/Feb/2017 23:48:49] “GET / HTTP/1.1” 200 -

^CjiangyinadeMacBook-Pro:flask-deploy Yina$ ls
Procfile app.py requirements.txt

1
2

#### 登陆heroku

jiangyinadeMacBook-Pro:flask-deploy Yina$ heroku login
Enter your Heroku credentials.
Email: niceyina@gmail.com
Password (typing will be hidden):
Logged in as niceyina@gmail.com

1
2


jiangyinadeMacBook-Pro:flask-deploy Yina$ git status
On branch master

Initial commit

Untracked files:
(use “git add …” to include in what will be committed)

Procfile
app.py
requirements.txt

nothing added to commit but untracked files present (use “git add” to track)

1
2
3
4
5
6

jiangyinadeMacBook-Pro:flask-deploy Yina$ git remote



#### 初始化本地仓库

jiangyinadeMacBook-Pro:flask-deploy Yina$ git init
Reinitialized existing Git repository in /Users/Yina/Desktop/flask-deploy/.git/

1
2

#### 在heroku创建新应用

jiangyinadeMacBook-Pro:flask-deploy Yina$ heroku create –buildpack heroku/python
Creating app… done, ⬢ fathomless-gorge-35476
Setting buildpack to heroku/python… done
https://fathomless-gorge-35476.herokuapp.com/ | https://git.heroku.com/fathomless-gorge-35476.git

1
2


jiangyinadeMacBook-Pro:flask-deploy Yina$ git remote
heroku

jiangyinadeMacBook-Pro:flask-deploy Yina$ git status
On branch master

Initial commit

Untracked files:
(use “git add …” to include in what will be committed)

Procfile
app.py
requirements.txt

nothing added to commit but untracked files present (use “git add” to track)

1
2
3

#### 和heroku上的仓库关联
2次错误操作

jiangyinadeMacBook-Pro:flask-deploy Yina$ heroku git:remote -a flask-deploy
▸ You do not have access to the app flask-deploy.

jiangyinadeMacBook-Pro:flask-deploy Yina$ git:remote -a fathomless-gorge-35476
-bash: git:remote: command not found

1
2

正确操作

jiangyinadeMacBook-Pro:flask-deploy Yina$ heroku git:remote -a fathomless-gorge-35476
set git remote heroku to https://git.heroku.com/fathomless-gorge-35476.git

1
2


jiangyinadeMacBook-Pro:flask-deploy Yina$ git remote -v
heroku https://git.heroku.com/fathomless-gorge-35476.git (fetch)
heroku https://git.heroku.com/fathomless-gorge-35476.git (push)

jiangyinadeMacBook-Pro:flask-deploy Yina$ git status
On branch master

Initial commit

Untracked files:
(use “git add …” to include in what will be committed)

Procfile
app.py
requirements.txt

nothing added to commit but untracked files present (use “git add” to track)

1
2

#### 提交更新,建立版本

jiangyinadeMacBook-Pro:flask-deploy Yina$ git add .

jiangyinadeMacBook-Pro:flask-deploy Yina$ git commit -m “firsttry”
[master (root-commit) 9bee709] firsttry
3 files changed, 21 insertions(+)
create mode 100644 Procfile
create mode 100644 app.py
create mode 100644 requirements.txt

1
2

#### 推送到heroku远程仓库

jiangyinadeMacBook-Pro:flask-deploy Yina$ git push heroku master
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 544 bytes | 0 bytes/s, done.
Total 5 (delta 0), reused 0 (delta 0)
remote: Compressing source files… done.
remote: Building source:
remote:
remote: —–> Python app detected
remote: —–> Installing python-2.7.13
remote: $ pip install -r requirements.txt
remote: Collecting click==6.7 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 1))
remote: Downloading click-6.7-py2.py3-none-any.whl (71kB)
remote: Collecting Flask==0.12 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 2))
remote: Downloading Flask-0.12-py2.py3-none-any.whl (82kB)
remote: Collecting gunicorn==19.6.0 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 3))
remote: Downloading gunicorn-19.6.0-py2.py3-none-any.whl (114kB)
remote: Collecting itsdangerous==0.24 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 4))
remote: Downloading itsdangerous-0.24.tar.gz (46kB)
remote: Collecting Jinja2==2.9.5 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 5))
remote: Downloading Jinja2-2.9.5-py2.py3-none-any.whl (340kB)
remote: Collecting MarkupSafe==0.23 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 6))
remote: Downloading MarkupSafe-0.23.tar.gz
remote: Collecting requests==2.13.0 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 7))
remote: Downloading requests-2.13.0-py2.py3-none-any.whl (584kB)
remote: Collecting virtualenv==15.1.0 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 8))
remote: Downloading virtualenv-15.1.0-py2.py3-none-any.whl (1.8MB)
remote: Collecting Werkzeug==0.11.15 (from -r /tmp/build_187f6f6b2265aa103466132b777181bb/requirements.txt (line 9))
remote: Downloading Werkzeug-0.11.15-py2.py3-none-any.whl (307kB)
remote: Installing collected packages: click, itsdangerous, Werkzeug, MarkupSafe, Jinja2, Flask, gunicorn, requests, virtualenv
remote: Running setup.py install for itsdangerous: started
remote: Running setup.py install for itsdangerous: finished with status ‘done’
remote: Running setup.py install for MarkupSafe: started
remote: Running setup.py install for MarkupSafe: finished with status ‘done’
remote: Successfully installed Flask-0.12 Jinja2-2.9.5 MarkupSafe-0.23 Werkzeug-0.11.15 click-6.7 gunicorn-19.6.0 itsdangerous-0.24 requests-2.13.0 virtualenv-15.1.0
remote:
remote: —–> Discovering process types
remote: Procfile declares types -> web
remote:
remote: —–> Compressing…
remote: Done: 40.6M
remote: —–> Launching…
remote: Released v3
remote: https://fathomless-gorge-35476.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy… done.
To https://git.heroku.com/fathomless-gorge-35476.git

  • [new branch] master -> master
    jiangyinadeMacBook-Pro:flask-deploy Yina$
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129

    #3.5 微信服务版天气查询程序
    ### 任务
    ch7 目标:让用户通过微信和你的应用交互

    微信公众号开发:把应用部署到微信公众号的后台

    ### SAE
    ![](media/14885566591857/14886377111380.jpg)



    ![](media/14885566591857/14886422175914.jpg)

    请 把weatherquery.applinzi.com CNAME到weatherquery.applinzi.com,并 把a8e3c1d620.applinzi.com通过A记录解析到43.115.2.181完成域名身份验证。 域名身份验证将在SAE获取到相关DNS记录后完成(由于各地DNS Cache的影响,此过程可能需要较长时间,但一般情况下在您解析完验证域名后一天之内能完成验证)。 验证通过后,会自动为您完成域名绑定


    # 4 最初的目标

    在一开始的卡包里,大妈说:

    >“可以自己解决问题,是学习编程的根因之一。”


    知乎上,肖井陌写的[编程入门指南](https://zhuanlan.zhihu.com/p/19959253)说:

    > 这篇文章是写给那些真心想学编程的人看的——那些憋着一股狠劲,一定要做出什么真东西,不学好不罢休的人;而不是那些“听说编程好玩”的人,在我看来,这种人永远都入不了编程的门,更别提做出个像样的东西来了。


    这给我很大的警醒。学编程,必须有所出。如果没有像样的输出,一定是学无所得。我认真写了24k纯小白的教程,然而我如果无法实现哪怕一个我想解决的问题的话,教程就只剩鸡汤和缺乏系统的知识,毫无说服力了。

    回到第一部分,初学编程正念,最主要的就是不断反思自己为什么学习python,找自己想要解决的问题。

    考虑到我是纯小白,设置了第二个筛选条件:实现难度不要超过我的能力。

    基于以上2个,我提出以上这个项目。

    * **功能:**
    抓取用户在新浪微博中的历史记录,获得纯文本信息

    * **价值点:**
    - 好的想法都在平时点滴搜集。时间积累的想法会有很大的价值
    - 把内容完全托管第三方平台是有风险的。因为,它们会因为各种原因审核内容,让微博内容甚至账号消失

    这是我真的想做,并且功能少,感觉比较容易实现的功能。

    实现后,之后我希望再做一些拓展。我本人很想更深入对自然语言的文本做质性分析。这个功能可以帮助我快速搜集文本数据。


    ## 4.1 “我的档案”——新浪微博个人文本抓取项目

    [仓库地址](https://github.com/yiiina/mymemory-at-weibo)

    ### 项目概述
    **你在微博记录的美好小时光,迸发的思想火花,“我的档案”帮你备份**

    ### 项目简介

    **功能:**
    抓取用户在新浪微博中的历史记录,获得纯文本信息

    **价值点:**

    - 好的想法都在平时点滴搜集。时间积累的想法会有很大的价值
    - 把内容完全托管第三方平台是有风险的。因为,它们会因为各种原因审核内容,让微博内容甚至账号消失

    **目标用户:**

    * 长期在微博上进行创作,把自己想法写在微博上。
    * 希望定期以文本的方式备份自己在微博上的内容。


    ### 项目执行方案

    #### MVP 的核心功能是哪些?

    命令行界面完成
    输入微博账号
    输出该账号下的微博文本

    #### 开发的功能排期

    3.6-3.10 自由探索任务的思路
    3.11-3.12 碰头任务思路,任务分工
    3.13-3.17 完成任务
    3.17 19:42之前报名路演,确认顺序
    3.19-3.22 项目路演(微信群或者开智学堂APP的直播间)


    ## 4.2 项目思路
    ### 输入

    * 微博的网址url
    * 用户账号

    ### 输出

    * 网页文本数据

    ### 处理过程分析

    #### 程序如何和网页发出请求,返回数据?

    需要和网页进行交互,HTTP 协议。

    #### 选择什么模块 urllib requests bs4

    使用requests模块,对请求和接收的数据进行封装,通过HTTP协议传输数据。

    #### 数据如何处理

    #### 正则式表达是什么?

    #### 如何处理微博的反爬虫技术

    新浪微博的页面都是通过加密处理的吧,无法通过bs等来直接获取,尝试一下手机端的页面http://weibo.cn

    https://passport.weibo.cn/signin/welcome?entry=mweibo&r=http%3A%2F%2Fm.weibo.cn%2F

    ## 4.3 项目记录

    ### 建立仓库


    #### 在github新建仓库

    ![屏幕快照 2017-03-11 下午10.45.09](media/14892434101582/%E5%B1%8F%E5%B9%95%E5%BF%AB%E7%85%A7%202017-03-11%20%E4%B8%8B%E5%8D%8810.45.09.png)

    #### 选择第二种方法,在命令行界面,用git命令,建立和github关联的本地仓库

Yina$ cd /Users/Yina/Desktop/mymemory-at-weibo
jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ echo “mymemory-at-weibo”>>README.md
jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ git init
Initialized empty Git repository in /Users/Yina/Desktop/mymemory-at-weibo/.git/
jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ git status
On branch master

Initial commit

Untracked files:
(use “git add …” to include in what will be committed)

README.md

nothing added to commit but untracked files present (use “git add” to track)
jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ git add README.md
jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ git status
On branch master

Initial commit

Changes to be committed:
(use “git rm –cached …” to unstage)

new file:   README.md

jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ git commit -m “first commit”
[master (root-commit) 2a928c6] first commit
1 file changed, 1 insertion(+)
create mode 100644 README.md
jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ git remote add origin https://github.com/yiiina/mymemory-at-weibo.git
jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 226 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/yiiina/mymemory-at-weibo.git

  • [new branch] master -> master
    Branch master set up to track remote branch master from origin.
    jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$
    1
    2
    3
    4

    加上了-u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令

    第二次推送:

jiangyinadeMacBook-Pro:mymemory-at-weibo Yina$ git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 684 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To https://github.com/yiiina/mymemory-at-weibo.git
2a928c6..d98e377 master -> master
`

处理微博的反爬虫技术

新浪微博的页面都是通过加密处理的吧,无法通过bs等来直接获取,尝试一下手机端的页面http://weibo.cn

https://passport.weibo.cn/signin/welcome?entry=mweibo&r=http%3A%2F%2Fm.weibo.cn%2F

5 记录遇到的一些小白问题以及解决的过程

语法错误

比如:
错误:quit
正确:quit()

错误:elif:userinput == “help”:
正确:elif userinput == “help”:

错误:f=open(“weather_info”)
正确:f=open(“weather_info.txt”)

半角全角符号错误

CLI 文件路径

问题:找不到内置的tkinter~
python调用内置tkinter, tkinter封装了访问tk的接口
tk是图形库
tk调用系统提供的本地GUI接口,完成GUI
代码需要调用tkinter提供的接口
使用tkinter
from tkinter import

#!/usr/bin/python 与#!/usr/bin/env python的区别http://www.jianshu.com/p/96d02f07423d

安装 github,gitbook桌面端

gitbook editor 本地编辑
之前也是找不到gitbook editor的入口。下载下来,发现,哎,还挺好用的~要比网页端的gitbook流畅很多。

但是升级之后发现很难加载出来,有坑。

gitbook遇到过一个很严重的困难:之前的内容丢了,如何通过版本管理找回来?

6 学习心情手记:进错了教室之后

学习进行到三分之一的时候,意识到我走错了教室
作为真小白,每周都被暴击1万点
一下子回到高三,都是解不出的大分题目,太多坑要填!!!
然而自己报的课,跪在坚持Orz

任务提交感受

入学任务:最困难的是使用CLI

《learn python the hard way》E0-E17
CLI花了很长时间,0-17的代码,抄进去,只要认真点,也是可以顺利通过的。就是不懂什么意思就是了。

ch0 python2 & python3

这时候其实不太懂,但是因为任务也是很容易混的~
选择最easy模式,也是可以混过去的,所以那个时候我只看任务,不看文档。

任务:在《learn python the hard way》中选择3-8个练习,用pyhon3改写
课程任务提交到课程仓库issue中,folk课程仓库为个人仓库
写个人教程,并以gitbook发布

ch1 没有意识到自己是真小白

工作的原因,也不是很看重基础。只是想着完成任务就可以。
这个时候感觉到了难,但是没有意识到自己是真小白。python基本数据类型和控制流程没有概念。

本着坚持,不掉队的原则,目标是按时交任务
意料之中的遗憾是,姿势依然不算高级:
python任务,主要是参考了上海组的小伙伴们的作业(大家都好棒!!!)
git 看了一些资料,但是这次是来不及折腾了,下周开始,开始整理git的要点,实践git管理代码

姿势不高级的原因:

小白对基础知识还是不熟悉。
整理思路的过程中,也对任务进行了拆解,看了同学的作业,其实我的思路并没有大问题,也是找得到关键概念,但是,找不到解决问题的方法。把天气数据导入,需要用到dict这个功能,于是我把learn python the hard way的相关习题,做了一遍,但是这个练习题中的场景和我要做的场景并不是100%匹配,于是我依然很方。
好比学外语,记住了几个单词,但并不知道这些单词的语法和应用场景。

这周努力的方向,先以不高级的姿势完成任务,跟上队伍,同时补之前没有填上的坑:

  • 把《learn python the hard way》已完成的练习题中的代码用自己的理解,解释一遍,目标是能够把这些代码看得更真切~这是教程中的要点,怎么完成作业我把思路写在了代码里
  • 在看《世界是数字的》,我等小白该补的基础知识还是得补上~
  • 看了大妈推荐的《github入门与实践》,接下来的作业可以实(zhe)践(teng)起来
  • 下载了github客户端(白痴点:之前去appstore找没有找到),提升了一点点姿势水平

ch2 难到失去自我效能感,git初体验

交作业的感觉并不是太美好。不仅仅没能独立完成的,自主性发挥的空间都没有,我想边借鉴边自己想,但是运行同学代码的时候,感觉一个字不能动,不然就失败给你看。无奈,这周只能抄作业了。
但也不是完全没有进步,事实上填完了前两周的大坑,感觉还是很愉快的~

git和github的使用
之前看了一些概念,但没有get精髓,落实到行为上,姿势很low,基本上把github当成bbs和程序员界的社交网站

现在可以实现的是:通过folk,clone2个动作,结合桌面端的GitHub,把GitHub上好的代码直接弄到本地电脑,运行试看效果

最有意思的是填这个坑的场景
零基础小白,工作正忙且要哄完娃睡觉才能学习的我,很清楚知道是很难有时间精力保证可以独立完成任务的,所以我不会产生和“一定要独立完成,证明自己可以”的自尊心抵抗。

然而,连看同学作业的过程都没有那么顺利。复制黏贴代码之后,发现运行不成功,于是我去微信群求助,然后发现,这次任务有好几个python文件,我没有全部复制黏贴下来,代码不完整,就无法运行。
如果我要观摩好几个同学的作业,就得一个一个复制黏贴好麻烦,学习体验太差了有没有?

于是我就想到了GitHub的folk和clone的功能,此时此刻显得非常有必要,然后就折腾出来了。

通过这个过程中内心的纠结,切身体会到这个功能的需求场景了~

真的,即使没有独立完成CH2的任务,感觉也有收获

本次作业出现乔帮主点评OOP, 其实还说过一句话:好的艺术抄袭,伟大的艺术剽窃。Good artists copy, great artists steal。

万维刚分享过一个非常有趣的:我们该如何像别人学习呢?我们就如同小偷一样,到人家把厨房水槽之外的所有东西都搬走了——然后我们回过头去,把厨房水槽也搬走了。我们就是要用这种精神去学习。

关于本章节的重点:tkinter,类和对象

知识点大概看了一下,我觉得我理解这个概念了,虽然这个领域我还不会敲代码。我很喜欢这篇文章里超级英雄的举例,很生动。

另外总结了一个嵌套关系:变量套字符和数字,字符串可以套变量,函数可以套变量,对象套函数和数据。(不一定对,以后要在练习和实践中验证)

ch3 假期闭关

今年过了一个假年,没看节目,没出门拜年吃饭,除了带娃就是补python基础。
中间的感受是,自己一定是进错了教室。
知道了小白有2种:一种python基础弱,另一种是编程零基础小白。我是后一种。
要补的坑好多。
感谢这个假期,让我有了一个缓冲的时间,别人吃喝玩乐我在补坑。
不然接下来又要走得稀里糊涂了。
继续被虐是一定的。然而知道自己问题在哪里,和不知道自己问题在哪里,毕竟是两种学习境界。
文艺一点就是:
昨夜西风凋蔽树,独上高楼,望尽天涯路——不知路在何方
衣带渐宽终不悔,为伊消得人憔悴——路在脚下
编程语言的精准性,和诗歌基因冲突。想着不要写这种话的,想想开智也有独特的文艺气质,就不要忍住这种情绪抒发了吧。

假期的功课:

  • 把卡包重新刷了一遍
  • 做了一个小白进击路线,梳理了学习路径
  • 补充更新了ch0和ch1的个人教程
  • 把之前自己不会的,通过借鉴别人的作业完成的ch1,重新做了一遍
  • 回到ch3这个任务,80%是独立完成的,昨天晚上遇到一些问题,没有能运行成功,昨天晚上发布了一个issue。

@simpleowen和@stuian同学帮我修改了一些问题,并且他们运行成功了。截图是@stuian同学贴上来的。
我在公司电脑没有安装python,要回家再试。我先改好了代码,把作业交上来先。
不管如何,这周完成任务的姿势水平,和前两周相比,也是有进步了。

ch4 拿银子换时间

和其他同学一样,通过刷《flask web开发:基于python的web应用开发实践》的前面4章来做这个任务。但是一步一步跟着做完,并没有预期那样有做任务的思路。
原因主要是,之前ch2的时候,对于面向对象编程和类的概念,停留在一种思想上,而没有进一步掌握如何在编程中去运用这种编程思想。模块多的时候,我就凌乱了~
因为@VyGiBe 也是刷这本书完成的,所以就先借他的交了任务再说。
有一种感觉,学习困难的东西,会让其他那些任务变得更简单~比如说工作,工作中获得别人的认可也很开心。
这周工作也很忙,已经尽量在抽时间学习了。打车上下班~ 哗哗的银子换时间。没有靠自己完成任务,已经不那么纠结了,寸进也有寸进的欢喜~

ch6 最简单的flask应用在heroku上的部署,没有实现天气查询的功能

image

困在了一些问题上面,发了两篇issue.
困难的原因是:
之前留的坑:git 命令没用过,ch4稀里糊涂抄袭程度100%
新的问题:Heroku Buildpacks,Procfile

两者混在一起,就很辣手

大妈的建议是冷冻疗法:

杀光,
重新部署
从0开始, 一步步进行
先完成一个干净的无/最小 app 的空间部署
再逐步追加
直到发现崩溃的那一个配置行

采取了这个建议,再结合一个很清楚的youtube视频,完成了一个最简单的flask应用在heroku上的部署。

收获:
练习git命令的多种使用场景
通过冷冻疗法,也大概清楚该如何填ch4留下来的坑了

日常折腾

2017-01-19 假期补坑:嵌套公式

看了廖雪峰的教程,但是内置的tkinter调取不出来。
看了面向对象编程的思想,感觉自己懂了。想到之前自己总结的嵌套公式,现在可以更近一步扩展:嵌套关系:变量套字符和数字,字符串可以套变量,函数可以套变量,对象套函数和数据。
看这些代码,感觉不那么像天书了。也是一个进步吧。

2017-01-27 假期补坑:git github gitbook

6号-27号,写git github gitbook的教程,顺便补之前的坑。

2017-01-28 假期补坑:python基础环节

今天到python基础环节。
看完的感觉是:这部分才是值得花大力气的。作为零基础,真的是最薄弱的环节,如果真的把这部分捋顺,ch1可能就会简单很多了。

2017-01-29 假期补坑:python

2017-02-15 元气大伤 flask web框架开发

假期在家7天闭关用功。感觉做完ch3有点信心了。
ch4也很用功。为了省时间学习每天打车上下班。买了《flask web开发:基于python的web应用开发实践》每天刷到深夜。
然而还是不会做。

又气又累。给自己放了2天假。不去学习新的知识。先放空。

然后再梳理一下自己的路途。当时绕过的坑,该补还得补,当时糊弄的还是得补牢。

2017-02-23 自我怀疑的日常

报了python班,真是自虐。一周一周的蓬头垢面,最近都没什么可以上镜的照片拍出来了。真的很累,而且觉得不开心。
会怀疑自己的选择。这个和工作有啥关系呢?我也不会转行当程序员啊?程序员那么苦,我干嘛虐自己呢?要这么有职业危机感吗?

还有大作业,做啥有价值呢?
我想做把自己微博上的内容都下载下来;我想做个人网站;还有什么痛点可以做?可是,难的我不会,想做的太难。

想想也是很坑爹,搞一个什么东西,发现基础体验都很差。gitbook老是打不开,老阳还把它捧得很高。真的是虐自己的时候不觉得虐吗?妈的,一切只能怪城墙。

heroku下载,注册,都tmd的其慢。做程序猿真的还是挺可怜的。

不过看到要学的还有2周,就觉得快熬到头了。

2017-03-03 MVP的保存和管理:git

这几周,暂且放下来了python,在git,github,gitbook的坑:

学习使用git,git的空间和时间概念,通过命令行在git本地仓库和github之间的互推,并且,也搞明白了如何通过summary文件及时同步至gitbook。

正好下周要部门内部分享。我问设计师你喜欢“设计师需要知道的心理学”还是“黑科技写作方法”,2个设计师都表示喜欢后者。

2017-03-05 部署到服务器的日记

上周交作业,发现自己不懂git的使用方法,以及不懂部署的内在逻辑。我按照最小mvp的走了一遍,但是并不懂那些命令在干嘛。

这周任务要把部署到服务器的应用接到微信上去。按照我一贯落后的风格,我还是把部署到服务器弄懂。

参考资料

极简编程导念
极简 Python 上手导念
自虐式 Pythonic 入门记要
廖雪峰的git教程
阮一峰Git远程操作详解